package com.comleader.uap.service;

import static cn.hutool.core.date.DateUtil.formatDateTime;
import static com.comleader.uap.common.util.StatUtil.*;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Service;

import com.comleader.uap.common.enums.StatDimensionEnum;
import com.comleader.uap.common.response.Result;
import com.comleader.uap.common.util.ExcelUtil;
import com.comleader.uap.common.util.ResponseUtil;
import com.comleader.uap.pojo.dto.FiveEffectStatDTO;
import com.comleader.uap.pojo.dto.OverrallIndicatorDTO;
import com.comleader.uap.pojo.query.FiveEffectQuery;
import com.comleader.uap.pojo.vo.FiveEffectStatVO;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * @Dscription 五保成效统计Service
 * @Author 连新景
 * @Date 2024/12/03 16:58
 */
@Slf4j
@AllArgsConstructor
@Service
public class FiveEffectStatService {
    private final CalledProtectPushService calledProtectPushService;
    private final InternetSmsService internetSmsService;
    private final ForwardingCancelService forwardingCancelService;

    public FiveEffectStatVO fiveEffectStat(FiveEffectQuery query) {
        CompletableFuture<FiveEffectStatVO.OverrallIndicator> overrallIndicatorFuture =
            CompletableFuture.supplyAsync(() -> selectOverrallIndicator(query)).exceptionally((exception) -> {
                log.error("查询总体指标异常", exception);
                return new FiveEffectStatVO.OverrallIndicator();
            });
        CompletableFuture<List<FiveEffectStatVO.Lists>> listFuture = CompletableFuture.supplyAsync(() -> selectList(query)).exceptionally((exception) -> {
            log.error("查询列表数据异常", exception);
            return ListUtil.empty();
        });
        CompletableFuture.allOf(overrallIndicatorFuture, listFuture);
        return new FiveEffectStatVO(overrallIndicatorFuture.join(), listFuture.join());

    }

    /**
     * @Description 查询总体指标
     * @Auhtor 连新景
     * @Date 2024/12/03 17:07
     * @param query
     * @return com.comleader.uap.pojo.vo.FiveEffectStatVO.OverrallIndicator
     */
    public FiveEffectStatVO.OverrallIndicator selectOverrallIndicator(FiveEffectQuery query) {
        FiveEffectStatVO.OverrallIndicator overrallIndicator = new FiveEffectStatVO.OverrallIndicator();
        OverrallIndicatorDTO.CalledProtect calledProtect = calledProtectPushService.countByActionStatus(query);
        OverrallIndicatorDTO.InternetSms internetSms = internetSmsService.countByProtectTypeAndDataType(query);
        Integer forwardingCancelNum = forwardingCancelService.countNum(query);
        BeanUtil.copyProperties(calledProtect, overrallIndicator);
        BeanUtil.copyProperties(internetSms, overrallIndicator);
        overrallIndicator.setForwardingCancelNum(forwardingCancelNum);
        return overrallIndicator;
    }

    /**
     * @Description 查询列表数据
     * @Auhtor 连新景
     * @Date 2024/12/04 14:40
     * @param query
     * @return java.util.List<com.comleader.uap.pojo.vo.FiveEffectStatVO.Lists>
     */
    public List<FiveEffectStatVO.Lists> selectList(FiveEffectQuery query) {
        query.setStartTime(query.getStatTime().get(0));
        query.setEndTime(query.getStatTime().get(1));
        StatDimensionEnum statDimensionEnum = getStatDimension(query.getStartTime(), query.getEndTime());
        query.setStatDimension(statDimensionEnum.getValue());
        List<FiveEffectStatDTO.CalledProtect> calledProtectList = calledProtectPushService.countByDimension(query);
        calledProtectList.forEach(data -> data.setStatTime(formatDatabaseTime(data.getStatTime(), statDimensionEnum)));
        Map<String, FiveEffectStatDTO.CalledProtect> calledProtectMap =
            CollStreamUtil.toIdentityMap(calledProtectList, FiveEffectStatDTO.CalledProtect::getStatTime);
        List<FiveEffectStatDTO.InternetSms> internetSmsList = internetSmsService.countByDimension(query);
        internetSmsList.forEach(data -> data.setStatTime(formatDatabaseTime(data.getStatTime(), statDimensionEnum)));
        Map<String, FiveEffectStatDTO.InternetSms> internetSmsMap = CollStreamUtil.toIdentityMap(internetSmsList, FiveEffectStatDTO.InternetSms::getStatTime);
        List<FiveEffectStatDTO.ForwardingCancel> forwardingCancelList = forwardingCancelService.countByDimension(query);
        forwardingCancelList.forEach(data -> data.setStatTime(formatDatabaseTime(data.getStatTime(), statDimensionEnum)));
        Map<String, FiveEffectStatDTO.ForwardingCancel> forwardingCancelMap =
            CollStreamUtil.toIdentityMap(forwardingCancelList, FiveEffectStatDTO.ForwardingCancel::getStatTime);
        List<FiveEffectStatVO.Lists> list = new ArrayList<>();
        List<String> statTimeList = getStatTimeList(query.getStartTime(), query.getEndTime());
        statTimeList.forEach(statTime -> {
            FiveEffectStatVO.Lists data = new FiveEffectStatVO.Lists();
            data.setStatTime(statTime);
            if (calledProtectMap.containsKey(statTime)) {
                data.setCalledProtectIssueNum(calledProtectMap.get(statTime).getCalledProtectIssueNum());
                data.setCalledProtectCancelNum(calledProtectMap.get(statTime).getCalledProtectCancelNum());
                data.setKickLineIssueNum(calledProtectMap.get(statTime).getKickLineIssueNum());
            } else {
                data.setCalledProtectIssueNum(0);
                data.setCalledProtectCancelNum(0);
                data.setKickLineIssueNum(0);
            }
            if (internetSmsMap.containsKey(statTime)) {
                data.setInternetProtectIssueNum(internetSmsMap.get(statTime).getInternetProtectIssueNum());
                data.setInternetProtectCancelNum(internetSmsMap.get(statTime).getInternetProtectCancelNum());
                data.setSmsProtectIssueNum(internetSmsMap.get(statTime).getSmsProtectIssueNum());
                data.setSmsProtectCancelNum(internetSmsMap.get(statTime).getSmsProtectCancelNum());
            } else {
                data.setInternetProtectIssueNum(0);
                data.setInternetProtectCancelNum(0);
                data.setSmsProtectIssueNum(0);
                data.setSmsProtectCancelNum(0);
            }
            if (forwardingCancelMap.containsKey(statTime)) {
                data.setForwardingCancelNum(forwardingCancelMap.get(statTime).getForwardingCancelNum());
            } else {
                data.setForwardingCancelNum(0);
            }
            list.add(data);
        });
        return list;
    }

    public void export(FiveEffectQuery query, HttpServletResponse response) throws IOException {
        List<Date> statTime = query.getStatTime();
        if (CollUtil.isEmpty(statTime) || statTime.size() != 2) {
            ResponseUtil.write(response, Result.fail("必须选择开始时间和结束时间"));
            return;
        }
        try {
            String fileName = "五保成效统计_" + formatDateTime(statTime.get(0)) + "_" + formatDateTime(statTime.get(1)) + ".xlsx";
            List<FiveEffectStatVO.Lists> list = selectList(query);
            ExcelUtil.exportMultipleSheet(response, fileName, FiveEffectStatVO.Lists.class, "五保成效统计", list);
        } catch (Exception e) {
            log.error("五保成效统计导出异常", e);
            ResponseUtil.write(response, Result.fail("系统异常"));
        }

    }

}
